package structs.book;

import java.io.Serializable;
import java.sql.SQLException;

import exception.InvalidEditionException;

/**
 * Represents a book. Contains publisher, author, title, edition, and ISBN.
 * @author SJP
 *
 */
public class Book implements Serializable{
	
	private static final long serialVersionUID = -5433398274770751426L;
	
	private String author,
				   title,
				   inv_num;
	private Editions eds = new Editions();
	private long ISBN;
	//private double price;
	private boolean changed = false;
	
	//private static Connection con;
	//private static PreparedStatement selISBN, selID, insert, update;
	
	public static Book LM = new Book("MTU","Custom Lab Manual",2L,"","LM"),
						NT = new Book("","No Text",0L,"","NT"),
						NA = new Book("","No Info",1L,"","NA");
	
	public Book(String auth, String t, long isbn, Edition ed, String invNum){
		author = auth;
		title = t;
		ISBN = isbn;
		inv_num = invNum;
		eds.add(ed);
	}
	
	/**
	 * Create a new books with the given author, title, edition, isbn
	 * @param auth
	 * @param t
	 * @param isbn
	 * @param ed
	 * @throws NumberFormatException
	 * @throws SQLException
	 */
	public Book(String auth, String t, long isbn, String ed, String invNum) throws NumberFormatException{
		this(auth,t,isbn,new Edition(ed,0.0),invNum);
	}
	
	private Book() {
		
	}
	
	/**
	 * MUST BE CALLED BEFORE CREATING ANY BOOK OBJECTS.
	 * Saves a reference to the current db connection and initializes
	 * the prepared statements to select, insert, or update a book in the db.
	 * @param c
	 * @throws SQLException
	 */
	/*public static void setCon(Connection c) throws SQLException {
		con = c;
		try {
			prepareStmts();
		} catch (SQLException e) {
			// table does not exist.
			Statement stmt = getStatement();
			stmt.execute("create table books (author varchar(15), title varchar(75), isbn varchar(13), ed varchar(10), inv_num varchar(7))");
			prepareStmts();
		}
	}
	
	private static void prepareStmts() throws SQLException {
		selISBN = con.prepareStatement("select * from books where isbn = ?");
		selID = con.prepareStatement("select * from books where inv_num = ?");
		insert = con.prepareStatement("insert into books (author, title, isbn, ed, inv_num) values (?,?,?,?,?)");
	}
	
	public static Statement getStatement() throws SQLException {
		return con.createStatement();
	}*/
	
	public String getInsert() {
		return "insert into books (isbn, author, title, ed, price) values (\'"+getISBN()+"\',\'"+getAuthor()+"\',\'"+getTitle()+"\',\'"+getEd()+"\',"+getPrice()+")";
	}
	
	public String getUpdate() {
		return "update books set price="+getPrice()+" where isbn = "+getISBN();
	}
	
	/**
	 * Retrieve a book record from the db with the given ISBN
	 * @param isbn
	 * @return
	 * @throws SQLException
	 */
	/*public static Book getInstance(long isbn) throws SQLException {
		Book out = new Book();
		
		checkCon();
		
		selISBN.setLong(1, isbn);
		selISBN.execute();
		
		ResultSet result = selISBN.getResultSet();
		if (!result.next())
			throw new SQLException("Book does not exist.");
		else {
			out.setAuthor(result.getString("author"));
			out.setTitle(result.getString("title"));
			out.setEdition(result.getString("ed"));
			//out.setPrice(result.getDouble("price"));
		}
		
		return out;
	}*/
	
	/**
	 * @return the inv_num
	 */
	public String getInv_num() {
		return inv_num;
	}

	/*private static void checkCon() throws SQLException{
		if (con == null)
			throw new SQLException("Bad Connection");
	}
	
	public static Book get(String id) throws SQLException {
		Book out = new Book();
		
		checkCon();
		
		selID.setString(1, id);
		selID.execute();
		
		ResultSet result = selID.getResultSet();
		if (!result.next())
			throw new SQLException("Book does not exist.");
		else {
			out.setAuthor(result.getString("author"));
			out.setTitle(result.getString("title"));
			out.setEdition(result.getString("ed"));
			//out.setPrice(result.getDouble("price"));
		}
		
		return out;
	}*/
	
	/**
	 * @param author the author to set
	 */
	private void setAuthor(String author) {
		this.author = author;
	}

	/**
	 * @param title the title to set
	 */
	private void setTitle(String title) {
		this.title = title;
	}

	/**
	 * @param edition the edition to set
	 */
	private void setEdition(String edn) {
		setEdition(edn,0.0);
	}
	
	private void setEdition(String edn, double p) {
		setEdition(new Edition(edn,p));
	}
	
	private void setEdition(Edition e) {
		eds.add(e);
	}
	
	private String getEd() {
		return getEdition().getEd();
	}
	
	/**
	 * @return the author of this book
	 */
	public String getAuthor() {return author;}
	
	/**
	 * @return the title of this book
	 */
	public String getTitle() {return title;}
	
	/**
	 * @return the ISBN of this book
	 */
	public long getISBN() {return ISBN;}
	
	/**
	 * @return the edition of this book
	 * @throws InvalidEditionException 
	 */
	public Edition getEdition() {return eds.getMostRecent();}
	
	public Editions getEditions() {return eds;}
	
	/**
	 * @return the sale price of this book
	 */
	public double getPrice() {
		return eds.getMostRecent().getPrice();
	}
	
	/**
	 * Stores a new price for this book.
	 * @param np new price
	 * @return the new price
	 * @throws InvalidEditionException 
	 */
	//public double setPrice(double np) throws InvalidEditionException {return eds.getMostRecent().setPrice(np);}
	
	/**
	 * @return Author Title Edition ISBN
	 */
	@Override
	public String toString() {return getAuthor()+" "+getTitle()+" "+getEd()+" "+getISBN();}
	
	/*public void insert() throws SQLException {
		
		try {
			//System.out.println("Is the book in the DB?");
			Book.getInstance(ISBN);
			//System.out.println("yes. do nothing");
		}
		catch (SQLException e) {
			//System.out.println(e.getMessage());
			
			Statement stmt = con.createStatement();
			stmt.executeBatch();
			//System.out.println("Book "+getTitle()+" added successfully");
		}
	}*/

	public void cleanUp() throws SQLException {
		
		if (!changed )
			return;
	}
}
